package org.hgvc.webapp.ets.spring.service;


import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.hgvc.webapp.ets.bo.ActionBulletin;
import org.hgvc.webapp.ets.bo.AdvancePayment;
import org.hgvc.webapp.ets.bo.Agreement;
import org.hgvc.webapp.ets.bo.CreditNote;
import org.hgvc.webapp.ets.bo.DocControl;
import org.hgvc.webapp.ets.bo.Finance;
import org.hgvc.webapp.ets.bo.Invoice;
import org.hgvc.webapp.ets.bo.InvoiceDtl;
import org.hgvc.webapp.ets.bo.Member;
import org.hgvc.webapp.ets.bo.MemberComp;
import org.hgvc.webapp.ets.bo.MemberInd;
import org.hgvc.webapp.ets.bo.MemberInstallmentPlan;
import org.hgvc.webapp.ets.bo.MemberPointEntitle;
import org.hgvc.webapp.ets.bo.MemberTransaction;
import org.hgvc.webapp.ets.bo.MemberTransactionEntitlement;
import org.hgvc.webapp.ets.bo.Membership;
import org.hgvc.webapp.ets.bo.MembershipChangeLog;
import org.hgvc.webapp.ets.bo.Payment;
import org.hgvc.webapp.ets.bo.PaymentDtl;
import org.hgvc.webapp.ets.bo.PointMembershipMap;
import org.hgvc.webapp.ets.bo.StandingInstruction;
import org.hgvc.webapp.ets.bo.XSInvoiceType;
import org.hgvc.webapp.ets.bo.XSMemberStatus;
import org.hgvc.webapp.ets.bo.XSMemberType;
import org.hgvc.webapp.ets.constant.ActionBulletinConstant;
import org.hgvc.webapp.ets.constant.AgreementConstant;
import org.hgvc.webapp.ets.constant.CommonConstant;
import org.hgvc.webapp.ets.constant.MemberConstant;
import org.hgvc.webapp.ets.constant.MembershipConstant;
import org.hgvc.webapp.ets.constant.PaymentConstant;
import org.hgvc.webapp.ets.constant.SystemConstant;
import org.hgvc.webapp.ets.constant.TerminateConstant;
import org.hgvc.webapp.ets.jsf.beans.admin.AdminViewMemberInfoBean;
import org.hgvc.webapp.ets.jsf.beans.agent.AgentViewMemberInfoBean;
import org.hgvc.webapp.ets.jsf.beans.finance.CreditNoteInfoBean;
import org.hgvc.webapp.ets.jsf.beans.finance.MemberInvListingInfoBean;
import org.hgvc.webapp.ets.jsf.beans.finance.PaymentInfoBean;
import org.hgvc.webapp.ets.spring.dao.AdminHbmDao;
import org.hgvc.webapp.ets.spring.dao.FinanceHbmDao;
import org.hgvc.webapp.ets.spring.dao.MemberHbmDao;
import org.jocsb.base.bo.User;
import org.jocsb.base.exception.BaseException;
import org.jocsb.base.spring.service.EmailManager;
import org.jocsb.base.util.DateUtil;
import org.jocsb.base.util.SpringUtils;
import org.jocsb.base.util.SystemUtil;

import com.j6.framework.util.J;


public class FinanceServiceImpl implements FinanceService{

	private FinanceHbmDao financeDao;
	private MasterSetupService masterSetupService;
	private EmailManager emailManager;
	private AdminHbmDao adminDao;
	private SystemService systemService;
	private MemberHbmDao dao; 
	private Integer noOfDaysDueDate;
	 
	private static final Logger log = Logger.getLogger(FinanceService.class);
	
	public void setNoOfDaysDueDate(Integer noOfDaysDueDate) {
		this.noOfDaysDueDate = noOfDaysDueDate;
	}
	public MemberHbmDao getDao() {
		return dao;
	}
	public void setDao(MemberHbmDao dao) {
		this.dao = dao;
	}
	public void setSystemService(SystemService systemService) {
		this.systemService = systemService;
	}
	public void setAdminDao(AdminHbmDao adminDao) {
		this.adminDao = adminDao;
	}
	public void setEmailManager(EmailManager emailManager) {
		this.emailManager = emailManager;
	}
	public void setFinanceDao(FinanceHbmDao financeDao) {
		this.financeDao = financeDao;
	}
	public void setMasterSetupService(MasterSetupService masterSetupService) {
		this.masterSetupService = masterSetupService;
	}

	public synchronized String getDocumentNo(String type)throws BaseException{
		String documentNo="";
		try{
			DocControl docControl = masterSetupService.getDocControlByType(type);
			if (docControl==null)
				throw new BaseException(SpringUtils.getMessage("error.doc.type.not.config", new Object[]{type}));

			StringBuffer numberBuf =new StringBuffer();
			numberBuf.append(docControl.getPrefix());
			long counter = docControl.getNumber()+1;
			long currentSize=new Long(String.valueOf(counter).length()).longValue();
			long size = docControl.getSize();
			for (long l=currentSize;l<size;l++){
				numberBuf.append("0");
			}
			numberBuf.append(counter);
			documentNo = numberBuf.toString();
			docControl.setNumber(counter);
			masterSetupService.updateDocControl(docControl);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.generate.doc.no", new Object[]{type}));
		}
		return documentNo;
	}



	public List<InvoiceDtl> getInvoiceDtlListByMemberId(String memberId)throws BaseException{
		try{
			return financeDao.getInvoiceDtlListByMemberId(memberId);
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.list.object", new Object[]{InvoiceDtl.class.getSimpleName()}));
		}
	}

	public AdvancePayment getAdvancePaymentByMemberId(String memberId)throws BaseException{
		try{
			return financeDao.getAdvancePaymentByMemberId(memberId);
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.get.object", new Object[]{AdvancePayment.class.getSimpleName()}));
		}
	}

	public Double getInvoiceCollectedAmountByMemberId(String memberId)throws BaseException{
		try{
			return financeDao.getTotalInvoicePaidAmountByMemberId(memberId);
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.get.invoice.sum.field", new Object[]{"Invoice Collected Amount"}));
		}
	}

	public Double getInvoiceAmountByMemberId(String memberId)throws BaseException{
		try{
			return financeDao.getTotalInvoiceAmountByMemberId(memberId);
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.get.invoice.sum.field", new Object[]{"Invoice Amount"}));
		}
	}

	public Invoice generateInvoiceForMemberInd(MemberInd memberInd,MemberInstallmentPlan memberInstallmentPlan,User user)throws BaseException{
		Invoice invoice=null;
		try{
			String newInvoiceNo=getDocumentNo(CommonConstant.DOC_TYPE_INVOICE);

			Finance fin = financeDao.getFinanceByMemberId(memberInd.getMember().getMemberId());
			if(fin==null){
				throw new BaseException(SpringUtils.getMessage("error.object.not.found", new Object[]{Finance.class.getSimpleName()}));
			}	

			invoice = new Invoice();
			invoice.setCreatedBy(user);
			invoice.setCreatedDate(new Date());
			invoice.setInvoiceAmount(memberInstallmentPlan.getInstallmentAmount());
			invoice.setInvoiceDate(new Date());
			invoice.setInvoiceNo(newInvoiceNo);
			invoice.setIsDeleted(CommonConstant.NOT_DELETED);
			invoice.setRefId(memberInd.getMember().getMemberId());
			invoice.setFinance(fin);
			financeDao.save(invoice);

			InvoiceDtl invoiceDtl=new InvoiceDtl();
			invoiceDtl.setInvoice(invoice);
			invoiceDtl.setCreatedBy(user);
			invoiceDtl.setCreatedDate(new Date());
			invoiceDtl.setIsDeleted(CommonConstant.NOT_DELETED);
			invoiceDtl.setItemAmount(invoice.getInvoiceAmount());
			invoiceDtl.setItemType(CommonConstant.INVOICE_TYPE_INSTALLMENT);
			invoiceDtl.setStatus(CommonConstant.INVOICE_STATUS_ACTIVE);
			invoiceDtl.setItemDesc(memberInstallmentPlan.getInstallmentItem());

			financeDao.save(invoiceDtl);
		}catch(BaseException be){
			throw be;
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.generate.member.invoice", new Object[]{}));

		}
		return invoice;
	}

	
	//alan start
	public Object[] getMemberPaymentInfoByPaymentId(String paymentId) throws BaseException{

		try{
			PaymentDtl paymentDtl = financeDao.getPaymentDtlByPaymentId(paymentId);
			Payment payment = paymentDtl.getPayment();
			List<InvoiceDtl> list = financeDao.getInvoiceDtlByPaymentId(paymentId);
			Agreement agreement = (Agreement)financeDao.getObject(Agreement.class, payment.getRefId());
			StandingInstruction instruction = financeDao.getStandingInstructionByPaymentId(payment.getPaymentId());
			Member member = agreement.getMember();

			Object[] array = new Object[6];
			array[0] = payment;
			array[1] = paymentDtl;
			array[2] = list;
			array[3] = member;
			array[4] = instruction;
			array[5] = agreement;
			return array;

		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.member.payment.info", new Object[]{}));
		}
	}


	public void approveNewAgreement(Member member,Agreement agreement,Payment payment,User user,String reason,String actionNo)throws BaseException{
		try{

			payment.setStatus(PaymentConstant.PAYMENT_STATUS_ACK);
			payment.setAckUser(user);
			payment.setAckDate(new Date());
			payment.setModifiedBy(user);
			payment.setModifiedDate(new Date());

			financeDao.update(payment);

			agreement.setPaymentStatus(AgreementConstant.AGREEMENT_PAYMENT_STATUS_ACK_DEPOSIT);
			agreement.setModifiedBy(user);
			agreement.setModifiedDate(new Date());
			financeDao.update(agreement);

			//generate point
			/*Membership membership = agreement.getMembership();
			List<PointMembershipMap> pointList = dao.getPointMembershipMapList(membership.getMembershipId());
			Calendar calendar = GregorianCalendar.getInstance();
			calendar.setTime(new Date());
			int year = calendar.get(Calendar.YEAR);
			for(PointMembershipMap map:pointList){
				MemberPointEntitle entitle = new MemberPointEntitle();
				entitle.setPoint(map.getPoint());
				entitle.setAgreement(agreement);
				entitle.setYear(new Integer(year));
				entitle.setPointCategory(map.getPointCategory());
				entitle.setCreatedBy(SystemConstant.SYSTEM_USER);
				entitle.setCreatedDate(new Date());
				entitle.setStatus(MemberConstant.MEMBER_POINT_VALID);
				dao.save(entitle);
			}*/
			systemService.deleteActionBulletinByActionNo(actionNo);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.approve.new.agreement", new Object[]{}));
		}
	}


	public void memberPaymentClearance(Member member,Agreement agreement,Payment payment,User user,String password,String reason,String actionNo,List<InvoiceDtl> list)throws BaseException{
		try{
			
			System.out.println(" \n\n testing testing .........");
			
			payment.setStatus(PaymentConstant.PAYMENT_STATUS_ACK);
			payment.setAckUser(user);
			payment.setAckDate(new Date());
			payment.setModifiedBy(user);
			payment.setModifiedDate(new Date());
			financeDao.update(payment);
			systemService.deleteActionBulletinByActionNo(actionNo);
			
			for(InvoiceDtl dtl:list){
				dtl.setStatus(CommonConstant.INVOICE_STATUS_PAID);
				dtl.setModifiedBy(user);
				dtl.setModifiedDate(new Date());
				financeDao.update(dtl);
			}
			
			// insert agent commission payment
			//AgentCommission commission


		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException("");
		}
	}

	
	public void memberDepositPaymentClearance(Member member,Agreement agreement,Payment payment,User user,String password,String reason,String actionNo,List<InvoiceDtl> list, boolean addNewAgreementForExistMember)throws BaseException{
		try{

			password = SystemUtil.generatePassword(user.getUsername(), password);
			if(!password.equalsIgnoreCase(user.getPassword())){
				throw new BaseException(SpringUtils.getMessage("invalid.password", new Object[]{}));
			}

			payment.setStatus(PaymentConstant.PAYMENT_STATUS_ACK);
			payment.setAckUser(user);
			payment.setAckDate(new Date());
			payment.setModifiedBy(user);
			payment.setModifiedDate(new Date());

			financeDao.update(payment);
			
			for(InvoiceDtl dtl:list){
				dtl.setStatus(CommonConstant.INVOICE_STATUS_PAID);
				dtl.setModifiedBy(user);
				dtl.setModifiedDate(new Date());
				financeDao.update(dtl);
			}

			if(!addNewAgreementForExistMember){
				member.setStatus(MemberConstant.MEMBER_STATUS_PROSPECT_PENDING_AGREEMENT);
				member.setModifiedBy(SystemConstant.SYSTEM_USER);
				member.setModifiedDate(new Date());
				financeDao.update(member);
			}

			agreement.setPaymentStatus(AgreementConstant.AGREEMENT_PAYMENT_STATUS_ACK_DEPOSIT);
			agreement.setModifiedBy(user);
			agreement.setModifiedDate(new Date());
			financeDao.update(agreement);

			//send email notify user
			/*String subject = "Payment Successfully Received";
			String msg = "Payment Receipt No: "+payment.getReceiptNo()+"\n";
			msg += "Payment Amount: "+payment.getPaymentAmount().toString()+"\n";
			emailManager.sendEmail(msg, member.getEmail(), subject, SystemConstant.SYSTEM_EMAIL);*/

			//create action bulletin member service admin for generate agreement
			/*List<User> usrList = adminDao.getUserByRole(SystemConstant.MEMBER_ADMIN_ROLE.getRoleId());
			for(User usr:usrList){*/
			
			//Added By Jacky 04-01-09 0918
			String memberName="";
			if (member.getMemberType().equalsIgnoreCase(CommonConstant.MEMBER_TYPE_IND)){
				MemberInd memberInd = dao.getMemberIndByMemberId(member.getMemberId());
				memberName=memberInd.getNameAsIcPassport();
			}else{
				MemberComp memberComp = dao.getMemberCompByMemberId(member.getMemberId());
				memberName = memberComp.getCompName();
			}
			
			if(member.getRegistrationType().equalsIgnoreCase(MemberConstant.MEMBER_REG_AGENT)){
				ActionBulletin ab = new ActionBulletin();
				ab.setActionBean(AgentViewMemberInfoBean.BEAN_NAME);
				ab.setActionMethod(AgentViewMemberInfoBean.AB_ACTION_INVOKE);
				ab.setActionCode(SpringUtils.getMessage("ab.member.pending.agreement.assign.enhanced", new Object[]{member.getMemberRegNo(),memberName}));
				ab.setActionParam1(member.getMemberId());
				ab.setActionParam2(agreement.getAgreementId());
			
				ab.setActionParam3(Boolean.toString(addNewAgreementForExistMember));
				ab.setCreatedBy(SystemConstant.SYSTEM_USER);
				ab.setCreatedDate(new Date());
				ab.setIsDeleted(CommonConstant.NOT_DELETED);
				ab.setType(ActionBulletinConstant.AB_ACTION_TYPE);
				ab.setActionNo(SystemUtil.getUniqueCode());
				systemService.createActionBulletinByUser(ab, member.getAgent().getRefUser());
				systemService.deleteActionBulletinByActionNo(actionNo);
				J.printPositif(ab.getActionNo()+"  =  "+ab.getActionParam3());
			}else{
				ActionBulletin ab = new ActionBulletin();
				ab.setActionBean(AdminViewMemberInfoBean.BEAN_NAME);
				ab.setActionMethod(AdminViewMemberInfoBean.AB_ACTION_INVOKE);
				ab.setActionCode(SpringUtils.getMessage("ab.member.pending.agreement.assign.enhanced", new Object[]{member.getMemberRegNo(),memberName}));
				ab.setActionParam1(member.getMemberId());
				ab.setActionParam2(agreement.getAgreementId());
				
				ab.setActionParam3(Boolean.toString(addNewAgreementForExistMember));
				ab.setCreatedBy(SystemConstant.SYSTEM_USER);
				ab.setCreatedDate(new Date());
				ab.setIsDeleted(CommonConstant.NOT_DELETED);
				ab.setType(ActionBulletinConstant.AB_ACK_TYPE);
				ab.setActionNo(SystemUtil.getUniqueCode());
				systemService.createActionBulletinByRoles(ab, SystemConstant.ADMIN_ROLE);
			//	systemService.createActionBulletinByRoles(ab, SystemConstant.MEMBER_SERVICE_ROLE);//Added by Jacky 19-OCT-2008 2134
				systemService.createActionBulletinByRoles(ab, SystemConstant.SALES_ADMIN_ROLE);//Added by Jacky 27-Nov-2008 1418
				systemService.deleteActionBulletinByActionNo(actionNo);
				J.printPositif(ab.getActionNo()+"  =  "+ab.getActionParam3());
			}

			//}

		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.confirm.prospect.payment", new Object[]{}));
		}
	}

	public void memberDepositPaymentRejection(Member member,Agreement agreement,Payment payment,User user,String password,String reason,String actionNo)throws BaseException{
		try{
			password = SystemUtil.generatePassword(user.getUsername(), password);
			if(!password.equalsIgnoreCase(user.getPassword())){
				throw new BaseException(SpringUtils.getMessage("invalid.password", new Object[]{}));
			}
			payment.setStatus(PaymentConstant.PAYMENT_STATUS_SUSPEND);
			payment.setAckUser(user);
			payment.setAckDate(new Date());
			payment.setModifiedBy(user);
			payment.setModifiedDate(new Date());
			payment.setReason(reason);
			financeDao.update(payment);
			//if(invoiceDtl.getItemType().equalsIgnoreCase(CommonConstant.INVOICE_TYPE_DEPOSIT)){
			//member.setPaymentStatus(MemberConstant.MEMBER_PAYMENT_STATUS_SUSPEND_DEPOSIT);
			member.setModifiedBy(SystemConstant.SYSTEM_USER);
			member.setModifiedDate(new Date());
			financeDao.update(member);

			agreement.setPaymentStatus(AgreementConstant.AGREEMENT_PAYMENT_STATUS_SUSPEND_DEPOSIT);
			agreement.setModifiedBy(SystemConstant.SYSTEM_USER);
			agreement.setModifiedDate(new Date());
			financeDao.update(agreement);
			//}

			//send email notify user
			String subject = "Payment Rejection Received";
			String msg = "Payment Receipt No: "+payment.getReceiptNo()+"\n";
			msg += "Payment Amount: "+payment.getPaymentAmount().toString()+"\n";
			msg += "Payment Rejection Reason: "+payment.getReason()+"\n";
			emailManager.sendEmail(msg, member.getEmail(), subject, SystemConstant.SYSTEM_EMAIL);

			//create action bulletin acknowledge admin user member payment rejection
			/*List<User> usrList = adminDao.getUserByRole(SystemConstant.MEMBER_ADMIN_ROLE.getRoleId());
			for(User usr:usrList){*/
			ActionBulletin ab = new ActionBulletin();
			ab.setActionBean("");//TODO
			ab.setActionMethod("");//TODO
			ab.setActionParam1(member.getMemberId());
			ab.setCreatedBy(SystemConstant.SYSTEM_USER);
			ab.setCreatedDate(new Date());
			ab.setIsDeleted(CommonConstant.NOT_DELETED);
			ab.setRole(SystemConstant.MEMBER_ADMIN_ROLE);
			ab.setType(CommonConstant.AB_TYPE_ROLE);
			ab.setActionCode("");//TODO
			financeDao.save(ab);
			//}

		}catch(BaseException be){
			be.printStackTrace();
			throw be;
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.reject.prospect.payment", new Object[]{}));
		}
	}

	public List<Payment> getRefundablePaymen(String memberId)throws BaseException{
		try{
			return  financeDao.getPaymentByMemberId(memberId, PaymentConstant.PAYMENT_STATUS_ACK);
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("", new Object[]{}));
		}
	}

	public CreditNote prospectRefundApproval(List<Payment> list,Member member,User user,double amt)throws BaseException{
		try{
			CreditNote creditNote = new CreditNote();
			creditNote.setCreditAmount(amt);
			creditNote.setCreditDate(new Date());
			creditNote.setCreditNo(getDocumentNo(CommonConstant.DOC_TYPE_CREDIT_NOTE));
			creditNote.setIsDeleted(CommonConstant.NOT_DELETED);
			creditNote.setCreatedBy(user);
			creditNote.setCreatedDate(new Date());
			financeDao.save(creditNote);

			for(Payment payment:list){
				payment.setModifiedBy(user);
				payment.setModifiedDate(new Date());
				payment.setStatus(PaymentConstant.PAYMEND_ACK_REFUND);
				payment.setCreditNote(creditNote);
				financeDao.update(payment);
			}
			member.setStatus(MemberConstant.MEMBER_STATUS_REFUNDED);
			member.setModifiedBy(user);
			member.setModifiedDate(new Date());
			financeDao.update(member);

			return creditNote;

		}catch(Exception be){
			be.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("", new Object[]{}));
		}
	}
	
	public List<MemberInvListingInfoBean> getMemberInvListingInfoBean(String memberSearch) throws BaseException {
		try{
			List<Agreement> list = dao.getAgreementListByMemberSearch(memberSearch);
			List<MemberInvListingInfoBean> resultList = new ArrayList<MemberInvListingInfoBean>();
			HashMap<String, XSMemberType> memberTypeHm = getMemberTypeHm();
			HashMap<String, XSMemberStatus> memberStatusHm = getMemberStatusHm();
			for(Agreement agreement:list){
				Member member = agreement.getMember();
				MemberInvListingInfoBean infoBean = new MemberInvListingInfoBean();
				infoBean.setAgreementId(agreement.getAgreementId());
				infoBean.setAgreementNo(agreement.getAgreetmentNo());
				if(member.getMemberType().equalsIgnoreCase(CommonConstant.MEMBER_TYPE_COMP)){
					MemberComp memberComp = dao.getMemberCompByMemberId(member.getMemberId());
					infoBean.setMemberName(memberComp.getCompName());
				}else{
					MemberInd memberInd = dao.getMemberIndByMemberId(member.getMemberId());
					infoBean.setMemberName(memberInd.getNameAsIcPassport());
				}
				infoBean.setMemberStatus(memberStatusHm.get(member.getStatus()).getDescription());
				infoBean.setMemberType(memberTypeHm.get(member.getMemberType()).getDescription());
				infoBean.setMemberId(member.getMemberId());
				infoBean.setMemberShipNo(member.getMembershipNo());
				infoBean.setCreatedDate(member.getCreatedDate());
				resultList.add(infoBean);
			}
			return resultList;
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.member", new Object[]{}));
		}
	}
	
	public HashMap<String, XSMemberType> getMemberTypeHm(){
		HashMap<String, XSMemberType> memberTypeHm = new HashMap<String, XSMemberType>();
		try {
			List<XSMemberType> memberTypeList = dao.getObjectList(XSMemberType.class);
			for(XSMemberType type : memberTypeList){
				memberTypeHm.put(type.getCode(), type);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return memberTypeHm;
	}
	
	public HashMap<String, XSMemberStatus> getMemberStatusHm(){
		HashMap<String, XSMemberStatus> memberStatusHm = new HashMap<String, XSMemberStatus>();
		try {
			List<XSMemberStatus> memberStatusList = dao.getObjectList(XSMemberStatus.class);
			for(XSMemberStatus status : memberStatusList){
				memberStatusHm.put(status.getCode(), status);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return memberStatusHm;
	}
	
	public List<MemberInvListingInfoBean> getInvListByAgreementId(String agreementId) throws BaseException {
		List<MemberInvListingInfoBean> resultList = new ArrayList<MemberInvListingInfoBean>();
		try {
			HashMap<String, XSInvoiceType> invoiceTypeHm = getInvoiceTypeHm();
			List<InvoiceDtl> invDtlList = dao.getInvoiceDtlListByAgreementId(agreementId);
			for(InvoiceDtl dtl : invDtlList){
				MemberInvListingInfoBean infoBean = new MemberInvListingInfoBean();
				infoBean.setInvNo(dtl.getInvoice().getInvoiceNo());
				infoBean.setItemDescn(dtl.getItemDesc());
				infoBean.setItemType(invoiceTypeHm.get(dtl.getItemType()).getDescription());
				infoBean.setInvAmt(dtl.getItemAmount());
				infoBean.setAmtPaid(dtl.getPaidAmount());
				infoBean.setInvoiceDtl(dtl);
				resultList.add(infoBean);
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.list.agreement.invoice", new Object[]{}));
		}
		return resultList;
	}
	
	public HashMap<String, XSInvoiceType> getInvoiceTypeHm(){
		HashMap<String, XSInvoiceType> invoiceTypeHm = new HashMap<String, XSInvoiceType>();
		try {
			List<XSInvoiceType> invoiceTypeList = dao.getObjectList(XSInvoiceType.class);
			for(XSInvoiceType type : invoiceTypeList){
				invoiceTypeHm.put(type.getCode(), type);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return invoiceTypeHm;
	}

	public HashMap getFinListInvHm(String agreementId) throws BaseException {
		HashMap resultHm = new HashMap();
		try {
		//	System.out.println("----getFinListInvHm()--getInvListByAgreementId --start--"+new Date());
			List<MemberInvListingInfoBean> invList = getInvListByAgreementId(agreementId);
		//	System.out.println("----getFinListInvHm()--getAdvancePaymentAmtByAgreementId --start--"+new Date());
			Double advancePayment = getAdvancePaymentAmtByAgreementId(agreementId);
		//	System.out.println("----getFinListInvHm()--getFinanceByAgreementId --start--"+new Date());
			Finance finance = financeDao.getFinanceByAgreementId(agreementId);
		//	System.out.println("----getFinListInvHm()--getFinanceByAgreementId --end--"+new Date());
			resultHm.put("invList", invList);
			resultHm.put("advancePayment", advancePayment);
			resultHm.put("finance", finance);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultHm;
	}
	
	public List<AdvancePayment> getAdvancePaymentListByAgreementId(String agreementId) throws BaseException {
		List<AdvancePayment> advancePaymentList = new ArrayList<AdvancePayment>();
		try{
			advancePaymentList = financeDao.getAdvancePaymentListByAgreementId(agreementId);
			return advancePaymentList;
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.list.advance", new Object[]{InvoiceDtl.class.getSimpleName()}));
		}
	}
	
	public Double getAdvancePaymentAmtByAgreementId(String agreementId) throws BaseException {
		Double advancePaymenAmt = 0.0;
		try{
			List<AdvancePayment> advancePaymentList = financeDao.getAdvancePaymentListByAgreementId(agreementId);
			for(AdvancePayment payment : advancePaymentList){
				advancePaymenAmt = advancePaymenAmt + payment.getAmount();
			}
			return advancePaymenAmt;
		}catch(Exception ex){
			throw new BaseException(SpringUtils.getMessage("error.list.advance", new Object[]{InvoiceDtl.class.getSimpleName()}));
		}
	}
	
	public List<XSInvoiceType> getInvoiceTypeList() throws BaseException{
		List<XSInvoiceType> invoiceTypeList = new ArrayList<XSInvoiceType>();
		try {
			invoiceTypeList = dao.getObjectList(XSInvoiceType.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return invoiceTypeList;
	}
	public void saveInvoice(Invoice invoice, List<InvoiceDtl> invDtlList) throws BaseException {
		try {
			String newInvoiceNo=getDocumentNo(CommonConstant.DOC_TYPE_INVOICE);
			invoice.setInvoiceNo(newInvoiceNo);
			invoice.setInvoiceDate(new Date());
			Date dueDate = DateUtil.getNextDate(new Date(), noOfDaysDueDate);
			invoice.setInvoiceDueDate(dueDate);
			
			dao.save(invoice);
			dao.saveObjects(invDtlList);
		} catch (Exception e) {
			e.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.generate.invoice", new Object[]{InvoiceDtl.class.getSimpleName()}));
		}
		
	}
	public void saveCreditNote(List<CreditNoteInfoBean> creditNoteInfoList, User user) throws BaseException {	
		System.out.println("---saveCreditNote---");
		try {			
			HashMap<String, Double> totalCreditAmtByInvHm = new HashMap<String, Double>();
			// calculate invoiceDtl itemAmount : itemAmount = itemAmount - creditAmount
			for(CreditNoteInfoBean infoBean : creditNoteInfoList){
				Invoice invoice = infoBean.getInvoice();
				CreditNote creditNote = infoBean.getCreditNote();
				InvoiceDtl invoiceDtl = creditNote.getInvoiceDtl();
				invoiceDtl.setItemAmount(invoiceDtl.getItemAmount() - creditNote.getCreditAmount());
				dao.update(invoiceDtl);
				dao.save(creditNote);
				// if itemAmount < paidAmount, advancePayment = advancePayment + (paidAmount - itemAmount)
				System.out.println("amount="+invoiceDtl.getPaidAmount());
				if(invoiceDtl.getPaidAmount()>0){
					
					System.out.println("call updateAdvancePayment");
					
					updateAdvancePayment(invoiceDtl, user);
					
				}
				String key = invoice.getInvoiceId();
				if(totalCreditAmtByInvHm.containsKey(key)){
					Double totalCreditAmtByInv = totalCreditAmtByInvHm.get(key);
					totalCreditAmtByInv = totalCreditAmtByInv + creditNote.getCreditAmount();
				}else{
					Double totalCreditAmtByInv = creditNote.getCreditAmount();
					totalCreditAmtByInvHm.put(key, totalCreditAmtByInv);
				}
			} 
			
			// update invoice invoiceAmount : invoiceAmount = invoiceAmount - totalCreditAmtByInv
			updateInvoiceAmt(totalCreditAmtByInvHm);
			
			//throw new BaseException("debug stop");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void updateInvoiceAmt(HashMap<String, Double> adjustedAmtHm){
		try {	
			Set set= adjustedAmtHm.keySet(); 
			Iterator iter = set.iterator() ; 
			while (iter.hasNext()){  
				String invoiceId = (String) iter.next();
				Double adjustedAmt =  adjustedAmtHm.get(invoiceId);
				Invoice invoice = (Invoice) dao.getObject(Invoice.class, invoiceId);
				invoice.setInvoiceAmount(invoice.getInvoiceAmount() - adjustedAmt);
				dao.update(invoice);
			}  
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void updateAdvancePayment(InvoiceDtl invoiceDtl, User user){
		try {	
			if(invoiceDtl.getItemAmount()>invoiceDtl.getPaidAmount()){
				AdvancePayment advancePayment = financeDao.getAdvancePaymentByFinanceId(invoiceDtl.getInvoice().getFinance().getFinanceId());
				if(advancePayment==null){
					advancePayment = new AdvancePayment();
					advancePayment.setCreatedDate(new Date());
					advancePayment.setFinance(invoiceDtl.getInvoice().getFinance());
					advancePayment.setIsDeleted(CommonConstant.NOT_DELETED);
					advancePayment.setCreatedBy(user);
					advancePayment.setAmount(0.0);
					advancePayment.setAmount(advancePayment.getAmount() + invoiceDtl.getItemAmount() - invoiceDtl.getPaidAmount());
					dao.save(advancePayment);
				}else{
					advancePayment.setAmount(advancePayment.getAmount() + invoiceDtl.getItemAmount() - invoiceDtl.getPaidAmount());
					dao.update(advancePayment);
				}
			}else{
				//Paid Amount > Item Amount
				Double balance = invoiceDtl.getPaidAmount() - invoiceDtl.getItemAmount();
				if (balance.doubleValue()>0){
					updateAdvancePayment(invoiceDtl.getInvoice().getFinance(),  balance,user);
					invoiceDtl.setPaidAmount(invoiceDtl.getItemAmount());
					dao.update(invoiceDtl);
				}
			}
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void updateAdvancePayment(Finance finance, Double amount, User user){
		try {	
			AdvancePayment advancePayment = financeDao.getAdvancePaymentByFinanceId(finance.getFinanceId());
			if(advancePayment==null){
				advancePayment = new AdvancePayment();
				advancePayment.setCreatedDate(new Date());
				advancePayment.setFinance(finance);
				advancePayment.setIsDeleted(CommonConstant.NOT_DELETED);
				advancePayment.setCreatedBy(user);
				advancePayment.setAmount(0.0);
				advancePayment.setAmount(advancePayment.getAmount() + amount);
				dao.save(advancePayment);
			}else{
				advancePayment.setAmount(advancePayment.getAmount() + amount);
				dao.update(advancePayment);
			}
			
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void saveAdvancePayment(Payment payment, List<PaymentInfoBean> paymentInfoList, User user) throws BaseException {
		try {
			Double paymentAmt = 0.0;
			AdvancePayment advancePayment = financeDao.getAdvancePaymentByFinanceId(payment.getFinance().getFinanceId());
			if(advancePayment==null){
				advancePayment = new AdvancePayment();
				advancePayment.setCreatedDate(new Date());
				advancePayment.setFinance(payment.getFinance());
				advancePayment.setIsDeleted(CommonConstant.NOT_DELETED);
				advancePayment.setCreatedBy(user);
				advancePayment.setAmount(0.0);
				dao.save(advancePayment);
			}
			paymentAmt = advancePayment.getAmount();
			for(PaymentInfoBean infoBean : paymentInfoList){
				InvoiceDtl invoiceDtl = infoBean.getInvoiceDtl();
				PaymentDtl paymentDtl = infoBean.getPaymentDtl();
				if(paymentAmt>0)
					paymentAmt = processPayment(paymentAmt, invoiceDtl, paymentDtl);
			}
			payment.setPaymentAmount(paymentAmt);
			dao.save(payment);
			
			advancePayment.setAmount(paymentAmt);
			dao.update(advancePayment);
		} catch (Exception e) {
			e.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.knockoff.from.advance.payment", new Object[]{}));
		}
	}
	
	public List<Agreement> getValidAgreement(String memberId) throws Exception{
		List<Agreement> agreementMayExpired = dao.getAgreementListByMemberId(memberId);
		List<Agreement> agreementActive = new ArrayList<Agreement>();
		for (Agreement agreement2 : agreementMayExpired) {
			Calendar cal = DateUtil.setTime(agreement2.getAgreetmentDate());
			cal.add(Calendar.YEAR, agreement2.getMembership().getMembershipTerm());
			Date expiredDate = DateUtil.formatDateByTime(cal.getTime(), 23, 59, 59, 999);

			if (expiredDate.after(new Date())) {
				agreementActive.add(agreement2);
			}
		}
		return agreementActive;
	}
	
	public void savePayment(Payment payment ,List<PaymentInfoBean> paymentInfoList, Double paymentAmt, User user, String actionNo) throws BaseException {
		try {
			payment.setPaymentAmount(paymentAmt);
			payment.setPaymentDate(new Date());
			dao.save(payment);
			
			for(PaymentInfoBean infoBean : paymentInfoList){
				InvoiceDtl invoiceDtl = infoBean.getInvoiceDtl();
				PaymentDtl paymentDtl = infoBean.getPaymentDtl();
				
				//added by jimmy because there is no link from payment to invoice to calculate collection for commission
				//TODO must be full payment for invoice now. cant split one invoice few payment. because the design is invoice.paymentid
				invoiceDtl.getInvoice().setPayment(payment);
				invoiceDtl.getInvoice().setModifiedBy(user);
				invoiceDtl.getInvoice().setModifiedDate(new Date());
				//
				
				dao.update(invoiceDtl.getInvoice());
				if(paymentAmt>0){
					paymentAmt = processPayment(paymentAmt, invoiceDtl, paymentDtl);
					//added by jimmy for agreement transfer. if invoice paid
					if (invoiceDtl.getItemType().equalsIgnoreCase(CommonConstant.INVOICE_TYPE_AGREEMENT_TRANSFER)){
						Agreement agreement = (Agreement)dao.getObject(Agreement.class, invoiceDtl.getInvoice().getRefId());
						
						List<Agreement> agreements = getValidAgreement(agreement.getMember().getMemberId());
					
						agreement.setOldMember( agreement.getMember() );
						agreement.setMember(agreement.getNewMember());
						agreement.setNewMember(null);
						agreement.setModifiedBy(user);
						agreement.setModifiedDate(new Date());
						
						if (agreements.size()<2){

							agreement.getOldMember().setStatus(MemberConstant.MEMBER_STATUS_INACTIVE);
							agreement.getOldMember().getLoginUser().setStatus( CommonConstant.STATUS_NO);
							agreement.getOldMember().getLoginUser().setModifiedBy(user);
							agreement.getOldMember().setModifiedBy(user);
							agreement.getOldMember().setModifiedDate(new Date());
							dao.update(agreement.getOldMember().getLoginUser());
							dao.update(agreement.getOldMember());
							
						}
						
						agreement.getMember().setModifiedBy(user);
						agreement.getMember().setModifiedDate(new Date());
						agreement.getMember().setStatus(MemberConstant.MEMBER_STATUS_MEMBER);
						dao.update(agreement);
						dao.update(agreement.getMember());
						systemService.deleteActionBulletinByActionNo(actionNo);
						 
					}else if (invoiceDtl.getItemType().equalsIgnoreCase(CommonConstant.INVOICE_TYPE_DEPOSIT_MEMBERSHIP)){
						//TODO need to check if the payment not fully paid. but now dunt know when it goinf to update invoicedtl.satus to 'paid'
						Agreement agreement = (Agreement)dao.getObject(Agreement.class, invoiceDtl.getInvoice().getRefId());
						 
						Double paid = financeDao.getTotalPaidInstallment(agreement.getAgreementId());
						double totalAfterPay = MemberServiceImpl.getNewTotalPaymentPrice(agreement,agreement.getMembershipChangeLog().getToMembership(), paid);
						
						agreement.setMembership(agreement.getMembershipChangeLog().toMembership);
						agreement.setModifiedBy(user);
						agreement.setModifiedDate(new Date());
						dao.update(agreement); 
						
						MembershipChangeLog log= agreement.getMembershipChangeLog();
						log.setApprovedDate(new Date());
						dao.update(log);
						
						agreement.getMemberScheduleScheme().setTotalPrice(totalAfterPay);
						agreement.getMemberScheduleScheme().setModifiedBy(user);
						agreement.setFullMembershipPrice(agreement.getMembership().getMembershipFee());
						agreement.getMemberScheduleScheme().setModifiedDate(new Date());
						agreement.getMemberScheduleScheme().setInterestRate(agreement.getInstallmentSchema().getInterestRate());
						agreement.setMembershipChangeLog(null);
						dao.update(agreement.getMemberScheduleScheme());
						systemService.deleteActionBulletinByActionNo(agreement.getMembershipChangeLog().getActionNo()); 
						upgradeMemberPointEntitlement(  agreement,   log.getFromMembership(), user);
						 
					}else if (invoiceDtl.getItemType().equalsIgnoreCase(CommonConstant.INVOICE_TYPE_INSTALLMENT)){
						Agreement agreement = (Agreement)dao.getObject(Agreement.class, invoiceDtl.getInvoice().getRefId());
						
						agreement.getMemberScheduleScheme().setInstalledMonth(agreement.getMemberScheduleScheme().getInstalledMonth()+1);
//						if (invoiceDtl.getInvoice().getInvoiceAmount()>=outstanding){
//							agreement.setInstallmentSchema(null);
//							agreement.setMemberScheduleScheme(null);
//							
//						}
						agreement.setModifiedBy(user);
						agreement.setModifiedDate(new Date());
						dao.update(agreement);
						dao.update(agreement.getMemberScheduleScheme());
					}else if (invoiceDtl.getItemType().equalsIgnoreCase(CommonConstant.INVOICE_TYPE_INSTALLMENT_FULLPAYMENT)){
						Agreement agreement = (Agreement)dao.getObject(Agreement.class, invoiceDtl.getInvoice().getRefId());
//						double outstanding = agreement.getInstallmentSchema().getDepositPercent() * (
//								(agreement.getInstallmentSchema().getMonth() - agreement.getMemberScheduleScheme().getInstalledMonth())/ agreement.getMemberScheduleScheme().getTotalPrice());

						 
						agreement.setInstallmentSchema(null);
						agreement.setMemberScheduleScheme(null);
						 
						agreement.setModifiedBy(user);
						agreement.setModifiedDate(new Date());
						dao.update(agreement);
					}else if (invoiceDtl.getItemType().equalsIgnoreCase(CommonConstant.INVOICE_TYPE_ANNUAL_MAINTENANCE)){
						Agreement agreement = (Agreement)dao.getObject(Agreement.class, invoiceDtl.getInvoice().getRefId());
						 
						List<MemberPointEntitle>memberPointEntitles = dao.getHibernateTemplate().loadAll(MemberPointEntitle.class);
						int nextEntitlementYear=0;
						MemberPointEntitle latestMemberPointEntitle=null;
						Date nextEntitlementExpiredDate;
						
						for(MemberPointEntitle m : memberPointEntitles){
							if (nextEntitlementYear<m.getYear()){
								nextEntitlementYear =  m.getYear();
								latestMemberPointEntitle = m;
							}
						}
				 		nextEntitlementYear = nextEntitlementYear+2;
						Calendar c = DateUtil.setTime(latestMemberPointEntitle.getExpiryDate());
						c.add(2, Calendar.MONTH);
						nextEntitlementExpiredDate = c.getTime();
						 
						List<PointMembershipMap> pointList = dao.getPointMembershipMapList(agreement.getMembership().getMembershipId());
						Calendar calendar = GregorianCalendar.getInstance();
						calendar.setTime(new Date());
						
						for (PointMembershipMap map : pointList) {
							MemberPointEntitle entitle = new MemberPointEntitle();
							entitle.setPoint(map.getPoint());
							entitle.setAgreement(agreement);
							entitle.setYear(nextEntitlementYear);
							entitle.setPointCategory(map.getPointCategory());
							entitle.setCreatedBy(user);
							entitle.setCreatedDate(new Date());
							entitle.setStatus(MemberConstant.MEMBER_POINT_VALID);
							entitle.setIsDeleted(CommonConstant.NOT_DELETED);
							entitle.setExpiryDate(nextEntitlementExpiredDate);
							dao.save(entitle);
						}
						
						agreement.setAdvancedYear(0);//clear it
						agreement.setModifiedBy(user);
						agreement.setModifiedDate(new Date());
						dao.update(agreement);
						 
						insertMemberTransaction(agreement.getAgreementId(), "Advanced Entitlement. For agreement" + agreement.getAgreetmentNo() + " on year "+nextEntitlementYear);
						systemService.deleteActionBulletinByActionNo(actionNo);
 	
					}
				}
			}
			if(paymentAmt>0)
				updateAdvancePayment(payment.getFinance(),paymentAmt, user);
		} catch (Exception e) {
			e.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.knockoff.payment", new Object[]{}));
		}
	}
	
	/**
	 * replicate in memberservice
	 * @param agreement
	 *            new/toMembership inside agreement.getMember()
	 * @param OldMembership
	 * @throws Exception 
	 */
	public void upgradeMemberPointEntitlement(Agreement agreement, Membership oldMembership , User user) throws Exception{
// if (entitle.getPointCategory().getCode().equalsIgnoreCase(bookingPackage.getWePointCate().getCode())){
			
		String transMsg = "Upgrade membership "+ oldMembership.getMembershipCategory().getCode() + " to " + 
			agreement.getMembership().getMembershipCategory().getCode();
		
		
		Calendar c = com.j6.framework.util.DateUtil.setTime(new Date());
		int year = c.get(Calendar.YEAR);
		List<MemberPointEntitle> memberPointEntitles = dao.getValidMemberPointEntitleList(agreement.getAgreetmentNo(),year);
		
		List<PointMembershipMap> pointListNew = dao.getPointMembershipMapList(agreement.getMembership().getMembershipId());
		List<PointMembershipMap> pointListOld = dao.getPointMembershipMapList(oldMembership.getMembershipId());
		  
		for(PointMembershipMap newPointMembershipMap:pointListNew){
		 
			for(PointMembershipMap oldPointMembershipMap:pointListOld){
				if (oldPointMembershipMap.getPointCategory().getCode().equalsIgnoreCase(newPointMembershipMap.getPointCategory().getCode())){
					
					for(MemberPointEntitle entitle : memberPointEntitles){
						if (entitle.getPointCategory().getCode().equalsIgnoreCase(newPointMembershipMap.getPointCategory().getCode())){
							transMsg = transMsg + ". "+entitle.getPointCategory().getCode() + " from " + entitle.getPoint() +" to ";
							// TODO Low priority. How if upgrade point is less than previous.
								entitle.setPoint(entitle.getPoint()+(newPointMembershipMap.getPoint()-oldPointMembershipMap.getPoint()));
								transMsg = transMsg+  entitle.getPoint();
								entitle.setModifiedBy(user);
								entitle.setModifiedDate(new Date());
								dao.update(entitle);
						}
					}
				}
			}
 
		} 
		 
		insertMemberTransaction(agreement.getAgreementId(), transMsg);
	 
	}
	
	public void insertMemberTransaction(String agreementId, String transactionDesc) throws BaseException {
		try {
			MemberTransaction mt = new MemberTransaction();
			Agreement a = (Agreement) dao.getObject(Agreement.class, agreementId);
			mt.setAgreement(a);
			mt.setCreatedDate(new Date());
			mt.setIsDeleted(CommonConstant.NOT_DELETED);
			mt.setTransactionDate(new Date());
			mt.setTransactionDesc(transactionDesc);

			dao.save(mt);

			List<MemberPointEntitle> currentPointList = dao.getMemberPointEntitleActiveList(agreementId);

			for (MemberPointEntitle mpe : currentPointList) {
				MemberTransactionEntitlement mte = new MemberTransactionEntitlement();
				mte.setMemberTransaction(mt);
				mte.setCreatedDate(new Date());
				mte.setIsDeleted(CommonConstant.NOT_DELETED);
				mte.setPointBalance(mpe.getPoint());
				mte.setPointCategory(mpe.getPointCategory());
				mte.setReservedPoint(mpe.getReservedPoint());
				mte.setYear(mpe.getYear());
				mte.setExpiryDate(mpe.getExpiryDate());
				dao.save(mte);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.invoke.method",
					new Object[] { "insertMemberTransaction" }));
		}
	}
	public Double processPayment(Double paymentAmt, InvoiceDtl invoiceDtl, PaymentDtl paymentDtl) throws Exception {
		Double invoiceDtlPayAmt = invoiceDtl.getItemAmount() - invoiceDtl.getPaidAmount();
		if(invoiceDtlPayAmt>0){
			Double paidAmt = 0.0;
			if(paymentAmt>invoiceDtlPayAmt){
				paidAmt = invoiceDtlPayAmt;
			}else{
				paidAmt = paymentAmt;
			}
			invoiceDtl.setPaidAmount(invoiceDtl.getPaidAmount() + paidAmt);
			paymentDtl.setAmount(paidAmt);
			paymentAmt = paymentAmt - paidAmt;
			dao.save(paymentDtl);
			dao.update(invoiceDtl);
		}
		return paymentAmt;
	}
	
	public void autoSuspendUserAccount()throws BaseException{
		log.debug("Invoke autoSuspendUserAccount - started.");
		try{
			List<Finance> financeList = financeDao.getOverdueFinanceList();
			for (Finance f : financeList){
				Agreement a = f.getAgreement();
				Member m = a.getMember();
				User user = m.getLoginUser();
				
				if (!user.getStatus().equalsIgnoreCase(TerminateConstant.SUSPENDED)){
					user.setStatus(TerminateConstant.SUSPENDED);
					dao.update(user);
				}
			}
		}catch(Exception ex){
			ex.printStackTrace();
			throw new BaseException(SpringUtils.getMessage("error.invoke.method", new Object[]{"autoSuspendUserAccount"}));
		}finally{
			log.debug("Invoke autoSuspendUserAccount - completed.");
		}
	}
 
}
